#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <error.h>
#include <string>
bool SetSockfd(int sockfd)
{
    int flags = fcntl(sockfd, F_GETFL); // 获取当前文件描述符的信息
    if (flags < 0)
    {
        std::cout << "F_GETFL filed" << std::endl;
        return false;
    }
    int n = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); // 将文件描述符信息加上非阻塞设置进入文件描述符中
    if (n < 0)
    {
        std::cout << "F_SETFL filed" << std::endl;
        return false;
    }
    return true;
}
int main()
{
    // 将文件描述符设置为阻塞状态
    if (!SetSockfd(0))
    {
        return 1;
    }
    char buffer[1024];
    std::string tips = "please enter#";
    while (true)
    {
        write(0, tips.c_str(), tips.size());
        ssize_t n = read(0, buffer, sizeof(buffer));
        if (n > 0)
        {
            buffer[n] = 0;
            std::cout << "echo#" << buffer << std::endl;
        }
        else if (n == 0) // 读到文件结尾,正常结束
        {
            std::cout << "文件读取结束" << std::endl;
            break;
        }
        else // 读取失败,要么是底层资源没有准备好要么是读取失败了,这两种情况必须进行区分,因为后续处理是不一样的
        {
            //根据错误码进行区分错误原因
            if (errno == EAGAIN || errno == EWOULDBLOCK) // 两个错误码实际上是一样的,只用其中一个都可以
            {
                std::cout << "底层资源尚未准备好" << std::endl;
                sleep(1);
                continue;
            }
            else if(errno==EINTR)
            {
                std::cout<<"被中断,重头再来"<<std::endl;
                sleep(1);
                continue;
            }
            else
            {
                std::cout << "read filed" << std::endl;
                return 2;
            }
        }
    }
    return 0;
}